﻿/**
**		File : pak_kernel_win32.cpp
**		Author : beyondcode
**		Date : 2010/05/31
**		Des : beyondpak win32平台核心函数实现
**
**/

#include "pak_kernel_win32.h"


PPAK_DIR_STATUS_WIN32 _OpenDir_win32( const char* pszDir )
{
	PPAK_DIR_STATUS_WIN32 pDS = 0;
	PTCHAR ptszDir = 0;
	int nDirLen = 0;

	nDirLen = _U8ToT( pszDir, -1, 0, 0 );
	if( nDirLen<=0 )
		return pDS; 

	ptszDir = (PTCHAR)malloc( sizeof(TCHAR) * (nDirLen + 4) );
	if( !ptszDir )
		return pDS;

	_U8ToT( pszDir, -1, ptszDir, nDirLen );
	_ProcessPath_win32( ptszDir, _T("*.*") );

	pDS = (PPAK_DIR_STATUS_WIN32)malloc( sizeof( PAK_DIR_STATUS_WIN32 ) );
	if( !pDS )
		return pDS;

	pDS->hDir = INVALID_HANDLE_VALUE;
	pDS->ptszDir = ptszDir;
	pDS->bFirst = 1;
	
	_InitDir( &pDS->PakDir );
	return pDS;
}

const PPAK_DIR _ReadDir_win32( PAK_DIR_STATUS_WIN32* pDirStatus )
{
	PPAK_DIR pDir = 0;

	if( !pDirStatus )
		return 0;

	if( pDirStatus->bFirst )
	{
		HANDLE hFindFile = INVALID_HANDLE_VALUE;
		WIN32_FIND_DATA wfd;

		hFindFile = FindFirstFile( pDirStatus->ptszDir, &wfd );
		if( hFindFile==INVALID_HANDLE_VALUE )
			return 0;

		pDirStatus->bFirst = 0;
		pDirStatus->hDir = hFindFile;

		//处理获取到的文件/文件夹信息
		pDir = _ProcessDir_win32( pDirStatus, &wfd );
	}
	else
	{
		WIN32_FIND_DATA wfd;

		if( FindNextFile( pDirStatus->hDir, &wfd ) )
		{
			
			//处理获取到的文件/文件夹信息
			pDir = _ProcessDir_win32( pDirStatus, &wfd );
		}
		else
		{
			//遍历文件夹完毕
			return 0;
		}
	}

	return pDir;
}

int _CloseDir_win32( PPAK_DIR_STATUS_WIN32 pDirStatus )
{
	if( !pDirStatus )
		return 0;

	FindClose( pDirStatus->hDir );

	_ReleaseDir( &pDirStatus->PakDir );
	free( pDirStatus->ptszDir );
	free( pDirStatus );

	return 1;
}

PPAK_DIR _ProcessDir_win32( PPAK_DIR_STATUS_WIN32 pDirStatus, WIN32_FIND_DATA* pwfd )
{
	size_t nFileNameLen = 0;

	if( !pwfd )
		return 0;

	nFileNameLen = _TToU8( pwfd->cFileName, -1, 0, 0 );
	if( nFileNameLen<=0 )
		return 0;

	if( !_MallocDir( &pDirStatus->PakDir, nFileNameLen ) )
		return 0;

	if( !_TToU8( pwfd->cFileName, (size_t)-1, pDirStatus->PakDir.pszName, pDirStatus->PakDir.nNameLen ) )
			return 0;

	//File Type
	if( pwfd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
	{
		pDirStatus->PakDir.nType = DIRTYPE_DIR;
	}
	else
	{
		pDirStatus->PakDir.nType = DIRTYPE_FILE;
	}
	return &pDirStatus->PakDir;
}
void _ProcessPath_win32( PTCHAR ptszPath, PTCHAR ptszExt )
{
	size_t nLen = 0;
	
	if( !ptszPath || !ptszExt)
		return;
	
	nLen = _tcslen( ptszPath );
	if( 0==nLen )
		return;

	if( ptszPath[nLen-1] == _T('\\') )
	{
		_tcscat( ptszPath, ptszExt );
	}
	else
	{
		_tcscat( ptszPath, _T("\\") );
		_tcscat( ptszPath, ptszExt );
	}

}


int _AToU2_win32( const char* lpszSrcA, size_t nSrcALen, wchar_t* lpwszDestU2, size_t nDestU2Len )
{
	int ret = 0;

	ret = MultiByteToWideChar( CP_ACP, 0, lpszSrcA, -1, lpwszDestU2, (int)nDestU2Len );
	
	if( !ret )
	{
		_PrintConvertError_win32();
		return ret;
	}

	return ret;
}

int _AToU8_win32( const char* lpszSrcA, size_t nSrcALen, char* lpszDestU8, size_t nDestU8Len )
{
	int ret = 0;
	wchar_t* pwszBuffer = 0;

	ret = _AToU2_win32( lpszSrcA, nSrcALen, 0, 0 );
	if( !ret )
	{
		_PrintConvertError_win32();
		return ret;
	}

	pwszBuffer = (wchar_t*)malloc( sizeof(wchar_t) * ret );
	ret = _AToU2_win32( lpszSrcA, nSrcALen, pwszBuffer, ret );
	if( !ret )
	{
		_PrintConvertError_win32();
		free( pwszBuffer );
		return ret;
	}

	ret = _U2ToU8_win32( pwszBuffer, ret, lpszDestU8, nDestU8Len );
	if( !ret )
	{
		_PrintConvertError_win32();
		free( pwszBuffer );
		return ret;
	}
	free( pwszBuffer );
	return ret;
}

int _U2ToA_win32( const wchar_t* lpwszSrcU2, size_t nSrcU2Len, char* lpszDestA, size_t nDestALen )
{
	int ret = 0;

	ret = WideCharToMultiByte( CP_ACP, 0, lpwszSrcU2, (int)nSrcU2Len, lpszDestA, (int)nDestALen, 0, 0);

	if( !ret )
	{
		_PrintConvertError_win32();
		return ret;
	}
	return ret;
}
int _U2ToU8_win32( const wchar_t* lpwszSrcU2, size_t nSrcU2Len, char* lpszDestU8, size_t nDestU8Len )
{
	int ret = 0;

	ret = WideCharToMultiByte( CP_UTF8, 0, lpwszSrcU2, (int)nSrcU2Len, lpszDestU8, (int)nDestU8Len, 0, 0);
	
	if( !ret )
	{
		_PrintConvertError_win32();
		return ret;
	}
	return ret;
}
int _U8ToA_win32( const char* lpszSrcU8, size_t nSrcU8Len, char* lpszDestA, size_t nDestALen )
{
	int ret = 0;
	wchar_t* pwszBufferU2 = 0;

	ret = _U8ToU2_win32( lpszSrcU8, nSrcU8Len, 0, 0 );
	if( !ret )
	{
		_PrintConvertError_win32();
		return ret;
	}

	//pwszBufferU2 = new wchar_t[ ret ];
	pwszBufferU2 = (wchar_t*)malloc( sizeof(wchar_t) * ret );
	ret = _U8ToU2_win32( lpszSrcU8, nSrcU8Len, pwszBufferU2, ret );
	if( !ret )
	{
		_PrintConvertError_win32();
		return ret;
	}

	ret = WideCharToMultiByte( CP_ACP, 0, pwszBufferU2, (int)ret, lpszDestA, (int)nDestALen, 0, 0 );
	if( !ret )
	{
		_PrintConvertError_win32();
		return ret;
	}
	
	if( pwszBufferU2 )
		free( pwszBufferU2 );
	return ret;
}

int _U8ToU2_win32( const char* lpszSrcU8, size_t nSrcU8Len, wchar_t* lpwszDestU2, size_t nDestU2Len )
{
	int ret = 0;

	ret = MultiByteToWideChar( CP_UTF8, 0, lpszSrcU8, (int)nSrcU8Len, lpwszDestU2, (int)nDestU2Len );

	if( !ret )
	{
		_PrintConvertError_win32();
		return ret;
	}

	return ret;
}

void _PrintConvertError_win32()
{
	DWORD dwError = GetLastError();

	switch( dwError )
	{
	case ERROR_INVALID_FLAGS:
		{
			printf( "Error Invalid Flags\n" );
		}
		break;

	case ERROR_INVALID_PARAMETER:
		{
			printf( "Error Invalid Parameter\n" );
		}
		break;

	case ERROR_INSUFFICIENT_BUFFER:
		{
			printf( "Error Insufficient Buffer\n" );
		}
		break;

	case ERROR_NO_UNICODE_TRANSLATION:
		{
			printf( "Error No Unicode Translation\n" );
		}
		break;
	}
}
//Last Line for linux

